package com.plate.gateway.security.config;

import com.plate.gateway.config.SysParameterConfig;
import com.plate.gateway.security.expection.RequestAccessDeniedHandler;
import com.plate.gateway.security.expection.RequestAuthenticationEntryPoint;
import com.plate.gateway.filter.CorsFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
import org.springframework.security.web.server.authorization.AuthorizationContext;

/**
 * @ClassName SecurityConfig
 * @Description OAuth2.0相关配置
 * @Author jiaxd
 * @Date 2023年10月29日 19:14
 * @Version 1.0
 */

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 认证管理器
    @Autowired
    private ReactiveAuthenticationManager tokenAuthenticationManager;

    // 白名单配置
    @Autowired
    private SysParameterConfig sysParameterConfig;


    /**
     * JWT的鉴权管理器
     */
    @Autowired
    private ReactiveAuthorizationManager<AuthorizationContext> accessManager;

    @Autowired
    private RequestAuthenticationEntryPoint requestAuthenticationEntryPoint;

    @Autowired
    private RequestAccessDeniedHandler requestAccessDeniedHandler;

    @Autowired
    private CorsFilter corsFilter;



    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception{
        //认证过滤器，放入认证管理器tokenAuthenticationManager
        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(tokenAuthenticationManager);
        authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());

        http
                .httpBasic().disable()
                .csrf().disable()
//                .authorizeExchange()
//                //白名单直接放行
//                .pathMatchers(ArrayUtil.toArray(sysParameterConfig.getIgnoreUrls(),String.class)).permitAll()
//                //其他的请求必须鉴权，使用鉴权管理器
//                .anyExchange().access(accessManager)
//                //鉴权的异常处理，权限不足，token失效
//                .and().exceptionHandling()
//                .authenticationEntryPoint(requestAuthenticationEntryPoint)
//                .accessDeniedHandler(requestAccessDeniedHandler)
//                .and()
                // 跨域过滤器
                .addFilterAt(corsFilter, SecurityWebFiltersOrder.CORS)
                //token的认证过滤器，用于校验token和认证
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);
        return http.build();
    }

}
